package com.awa.usercenter.controller;

import com.aliyuncs.exceptions.ClientException;
import com.awa.usercenter.common.BaseResponse;
import com.awa.usercenter.common.Code;
import com.awa.usercenter.common.utils.RandomUtil;
import com.awa.usercenter.common.utils.ResultUtils;
import com.awa.usercenter.exception.BusinessException;
import com.awa.usercenter.model.code.CodeLoginRequest;
import com.awa.usercenter.model.domain.User;
import com.awa.usercenter.model.code.SendCodeRequest;
import com.awa.usercenter.model.domain.request.ForgetPassRequest;
import com.awa.usercenter.model.domain.request.UserLoginRequest;
import com.awa.usercenter.model.domain.request.UserRegisterRequest;
import com.awa.usercenter.service.CodeService;
import com.awa.usercenter.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.TimeUnit;

import static com.awa.usercenter.constant.UserConstant.USER_LOGIN_STATE;

/**
 * 用户接口
 */
@RestController
@Slf4j
@RequestMapping("/user")
@Tag(name = "用户相关接口")
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private CodeService codeService;
    @Autowired
    StringRedisTemplate redisTemplate;
    @PostMapping("/register")
    @Operation(summary = "用户注册")
    public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest){
        if(userRegisterRequest == null){
            throw new BusinessException(Code.PARAMS_ERROR);
        }
        //先取出来，再一个个校验
        String userPhone = userRegisterRequest.getUserPhone();
        String userPassword = userRegisterRequest.getUserPassword();
        String userCode = userRegisterRequest.getUserCode();
        //如果在传输数据上为空，则不进入业务层，在这返回
        if(StringUtils.isAnyBlank(userPhone, userPassword, userCode)){
            throw new BusinessException(Code.NULL_ERROR);
        }
        userService.userRegister(userPhone,userPassword,userCode);
        return ResultUtils.success("ok");
    }

    @PostMapping("/login")
    @Operation(summary = "用户登陆")
    public BaseResponse<String> userLogin(@RequestBody UserLoginRequest userLoginRequest){  //要指定请求对象;
        if(userLoginRequest == null)
        {
            throw new BusinessException(Code.NULL_ERROR);
        }
        // 先取出来，再一个个校验
        String userPhone = userLoginRequest.getUserPhone();
        String userPassword = userLoginRequest.getUserPassword();
        //如果在传输数据上为空，则不进入业务层，在这返回
        if(StringUtils.isAnyBlank(userPhone, userPassword)){
            throw new BusinessException(Code.NULL_ERROR);
        }
        String token = userService.userLoginToken(userPhone, userPassword);
        return ResultUtils.success(token);
    }

    @PostMapping("/logout")
    @Operation(summary = "用户注销")
    // 返回包装类，请求为空的时候也可以返回null
    public BaseResponse<Integer> userLogin(HttpServletRequest request){  //要指定请求对象
        if(request == null){
            throw new BusinessException(Code.NULL_ERROR);
        }

        int result = userService.userLogout(request);
        return ResultUtils.success(result);
    }

    @GetMapping("/profile")
    @Operation(summary = "获取当前用户")
    public BaseResponse<User> getCurrentUser(HttpServletRequest request){

        // 拿到userId的凭据
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        User currentUser = (User) userObj;
        if(currentUser == null){
            throw new BusinessException(Code.NULL_ERROR);
        }

        Long userId = currentUser.getUserId();
        // todo 校验用户是否合法
        return null;
    }

    /**
     * 发送短信
     * @param sendCodeRequest
     * @return
     */
    @PostMapping("/sms")
    @Operation(summary = "短信发送")
    public BaseResponse<String> sms(@RequestBody SendCodeRequest sendCodeRequest){
        // 1. 获取到手机号
        log.info(sendCodeRequest + "请求获取验证码");
        if(sendCodeRequest == null)
        {
            throw new BusinessException(Code.NULL_ERROR);
        }
        // 2. 模拟调用短信平台获取验证码，以手机号为KEY，验证码为值，存入Redis，过期时间5分钟
        String userPhone = sendCodeRequest.getUserPhone();
        String code = RandomUtil.randomNumbers();
        try {
            userService.sendsms(userPhone,code);
        } catch (ClientException e) {
            throw new RuntimeException(e);
        }
        log.info(userPhone + "生成验证码："+code);
        // 3. 返回过期时间，方便前端提示多少时间内有效
        // 前后台都需要限制一分钟之内，不能再次发送验证码
        // 5min过期时间
        redisTemplate.opsForValue().set(userPhone,code,5, TimeUnit.MINUTES);
        return ResultUtils.success("短信验证码发送成功");
    }
    //
    @PostMapping("/codelogin")
    @Operation(summary = "验证码登陆")
    public BaseResponse<String> codeLogin(@RequestBody CodeLoginRequest codeLoginRequest){
        // 先取出来，再一个个校验
        String phone = codeLoginRequest.getPhone();
        String smsCode = codeLoginRequest.getSmsCode();
        //如果在传输数据上为空，则不进入业务层，在这返回
        if(StringUtils.isAnyBlank(phone, smsCode)){
            throw new BusinessException(Code.NULL_ERROR);
        }
        String token = codeService.userCodeLoginToken(phone, smsCode);
        return ResultUtils.success(token);
    }
    @PostMapping("/forget")
    @Operation(summary = "忘记密码")
    public BaseResponse<String> forgetPassword(@RequestBody ForgetPassRequest forgetPassRequest){
        return userService.forgetPassHandler(forgetPassRequest);
    }

}
